package io.kiki.stack.netty.channelManager;

import io.kiki.stack.netty.lifeCycle.AbstractLifeCycle;
import io.kiki.stack.netty.lifeCycle.LifeCycleException;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;

@Slf4j
@Setter
@Getter
public class ReconnectManager extends AbstractLifeCycle {
    public final LinkedBlockingQueue<CreateChannelTask> queue;
    public final List<Url> canceled;
    public final ChannelManager channelManager;
    private Thread reconnectTaskThread;

    public ReconnectManager(ChannelManager channelManager) {
        this.channelManager = channelManager;
        this.queue = new LinkedBlockingQueue<CreateChannelTask>();
        this.canceled = new CopyOnWriteArrayList<Url>();
        // call startup in the constructor to be compatible with version 1.5.x
        startup();
    }


    @Override
    public void startup() throws LifeCycleException {
        // make the startup method idempotent to be compatible with version 1.5.x
        synchronized (this) {
            if (!isInited()) {
                super.startup();

                this.reconnectTaskThread = new Thread(new ReconnectTask(this));
                this.reconnectTaskThread.setName("-heal-channel-thread");
                this.reconnectTaskThread.start();
            }
        }
    }

    @Override
    public void shutdown() throws LifeCycleException {
        super.shutdown();

        this.reconnectTaskThread.interrupt();
        this.queue.clear();
        this.canceled.clear();
    }

    @Deprecated
    public void stop() {
        shutdown();
    }

    @Deprecated
    public void addReconnectTask(Url url) {
        ensureStarted();
        reconnect(url);
    }


    public void reconnect(Url url) {
        ensureStarted();
        queue.add(new CreateChannelTask(this, url));
    }

    @Deprecated
    public void addCancelUrl(Url url) {
        ensureStarted();
        disableReconnect(url);
    }


    public void disableReconnect(Url url) {
        ensureStarted();
        canceled.add(url);
    }

    @Deprecated
    public void removeCancelUrl(Url url) {
        ensureStarted();
        enableReconnect(url);
    }


    public void enableReconnect(Url url) {
        ensureStarted();
        canceled.remove(url);
    }


}
